package jumpingnotes.restlet.resource;

import java.util.HashMap;
import java.util.Map;

import jumpingnotes.model.entity.Activity;
import jumpingnotes.model.entity.ActivityMediaItem;
import jumpingnotes.model.entity.ActivityTemplate;
import jumpingnotes.model.entity.ActivityTemplateParam;
import jumpingnotes.model.entity.Audio;
import jumpingnotes.model.entity.Book;
import jumpingnotes.model.entity.BookComment;
import jumpingnotes.model.entity.BookFavorite;
import jumpingnotes.model.entity.BookTag;
import jumpingnotes.model.entity.BookTagRelation;
import jumpingnotes.model.entity.BookVersion;
import jumpingnotes.model.entity.Chapter;
import jumpingnotes.model.entity.ChapterVersion;
import jumpingnotes.model.entity.Deploy;
import jumpingnotes.model.entity.ErrorReport;
import jumpingnotes.model.entity.Friend;
import jumpingnotes.model.entity.FriendConfirm;
import jumpingnotes.model.entity.Group;
import jumpingnotes.model.entity.GroupAdmin;
import jumpingnotes.model.entity.GroupMember;
import jumpingnotes.model.entity.GroupMemberConfirm;
import jumpingnotes.model.entity.GroupTopic;
import jumpingnotes.model.entity.GroupTopicComment;
import jumpingnotes.model.entity.Member;
import jumpingnotes.model.entity.MemberConfirm;
import jumpingnotes.model.entity.MemberExperience;
import jumpingnotes.model.entity.Message;
import jumpingnotes.model.entity.RecordAlbum;
import jumpingnotes.model.entity.RecordTask;
import jumpingnotes.model.entity.SearchLog;
import jumpingnotes.model.entity.Sync;
import jumpingnotes.restlet.ErrorCode;
import jumpingnotes.security.Session;
import jumpingnotes.security.SessionManager;
import jumpingnotes.service.QueryService;

import org.json.JSONObject;
import org.restlet.Context;
import org.restlet.data.CharacterSet;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.resource.Resource;

public class BaseResource extends Resource
{
	public static final String SESSION_ID = "SESSION_ID";

	protected QueryService service;

	protected Session session;
	
	protected String sessionId;

	public static final Map<Class<?>, String[]> typeMap = new HashMap<Class<?>, String[]>();

	static
	{
		typeMap.put(Activity.class, new String[] { "Activity", "Activities" });
		typeMap.put(ActivityMediaItem.class, new String[] { "ActivityMediaItem", "ActivityMediaItems" });
		typeMap.put(ActivityTemplate.class, new String[] { "ActivityTemplate", "ActivityTemplates" });
		typeMap.put(ActivityTemplateParam.class, new String[] { "ActivityTemplateParam", "ActivityTemplateParams" });
		typeMap.put(Audio.class, new String[] { "Audio", "Audios" });
		typeMap.put(Book.class, new String[] { "Book", "Books" });
		typeMap.put(BookComment.class, new String[] { "BookComment", "BookComments" });
		typeMap.put(BookFavorite.class, new String[] { "BookFavorite", "BookFavorites" });
		typeMap.put(BookTag.class, new String[] { "BookTag", "BookTags" });
		typeMap.put(BookTagRelation.class, new String[] { "BookTagRelation", "BookTagRelations" });
		typeMap.put(BookVersion.class, new String[] { "BookVersion", "BookVersions" });
		typeMap.put(Chapter.class, new String[] { "Chapter", "Chapters" });
		typeMap.put(ChapterVersion.class, new String[] { "ChapterVersion", "ChapterVersions" });
		typeMap.put(Deploy.class, new String[] { "Deploy", "Deploys" });
		typeMap.put(ErrorReport.class, new String[] { "ErrorReport", "ErrorReports" });
		typeMap.put(Friend.class, new String[] { "Friend", "Friends" });
		typeMap.put(FriendConfirm.class, new String[] { "FriendConfirm", "FriendConfirms" });
		typeMap.put(Group.class, new String[] { "Group", "Groups" });
		typeMap.put(GroupAdmin.class, new String[] { "GroupAdmin", "GroupAdmins" });
		typeMap.put(GroupMember.class, new String[] { "GroupMember", "GroupMembers" });
		typeMap.put(GroupMemberConfirm.class, new String[] { "GroupMemberConfirm", "GroupMemberConfirms" });
		typeMap.put(GroupTopic.class, new String[] { "GroupTopic", "GroupTopics" });
		typeMap.put(GroupTopicComment.class, new String[] { "GroupTopicComment", "GroupTopicComments" });
		typeMap.put(Member.class, new String[] { "Member", "Members" });
		typeMap.put(MemberConfirm.class, new String[] { "MemberConfirm", "MemberConfirms" });
		typeMap.put(MemberExperience.class, new String[] { "MemberExperience", "MemberExperiences" });
		typeMap.put(Message.class, new String[] { "Message", "Messages" });
		typeMap.put(RecordAlbum.class, new String[] { "RecordAlbum", "RecordAlbums" });
		typeMap.put(RecordTask.class, new String[] { "RecordTask", "RecordTasks" });
		typeMap.put(SearchLog.class, new String[] { "SearchLog", "SearchLogs" });
		typeMap.put(Sync.class, new String[] { "Sync", "Syncs" });
	}

	public BaseResource()
	{
		super();
	}

	public BaseResource(Context context, Request request, Response response)
	{
		super(context, request, response);
	}

	public void checkPermission()
	{
		session = null;

		if (sessionId != null)
		{
			SessionManager sessionManager = service.getSessionManager();
			session = sessionManager.accessSession(sessionId);
		}
	}

	public boolean hasPermission()
	{
		return session != null || true;
	}

	/**
	 * Create an error json representation of error code.
	 */
	public JsonRepresentation createErrorRepresentation(ErrorCode errorCode)
	{
		try
		{
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("error", errorCode.getCode());

			return createJsonRepresentation(jsonObject);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * Create a json representation of json object.
	 */
	public JsonRepresentation createJsonRepresentation(JSONObject jsonObject)
	{
		if (jsonObject == null)
			return null;

		JsonRepresentation representation = new JsonRepresentation(jsonObject);
		representation.setMediaType(MediaType.APPLICATION_JSON);
		representation.setCharacterSet(CharacterSet.UTF_8);
		return representation;
	}

	/**
	 * Return the class type by class name
	 */
	public Class<?> getTypeByName(String name)
	{
		for (Class<?> type : typeMap.keySet())
		{
			String[] names = typeMap.get(type);
			if (names[0].equalsIgnoreCase(name) || names[1].equalsIgnoreCase(name))
			{
				return type;
			}
		}

		return null;
	}

	public void setService(QueryService service)
	{
		this.service = service;
	}
}
